package com.zxt.te.service.impl;

import com.alibaba.fastjson.JSON;
import com.zxt.te.client.MailClient;
import com.zxt.te.dto.SendEmailApiDTO;
import com.zxt.te.dto.UserTimeMailDTO;
import com.zxt.te.manager.UserManager;
import com.zxt.te.manager.UserTimeMailManager;
import com.zxt.te.model.User;
import com.zxt.te.model.UserTimeMail;
import com.zxt.te.service.UserTimeMailService;
import com.zxt.utils.AesUtils;
import com.zxt.utils.ZXTBeanUtils;
import com.zxt.utils.ZXTCollectionsUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author zxt
 */
@Slf4j
@Service
@AllArgsConstructor
public class UserTimeMailServiceImpl implements UserTimeMailService {

    private final UserTimeMailManager userTimeMailManager;
    private final UserManager userManager;
    private final MailClient mailClient;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void add(UserTimeMailDTO dto) {
        //生成加密盐值
        dto.setContentSalt(UUID.randomUUID().toString().replaceAll("-", ""));
        //使用Aes进行加密存储
        dto.setContent(AesUtils.encryption(dto.getContent(), dto.getContentSalt()));
        userTimeMailManager.save(ZXTBeanUtils.beanCopy(dto, UserTimeMail.class));
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, rollbackFor = Exception.class)
    public void dealSendUserTimeMail() {
        List<UserTimeMail> userTimeMailList = userTimeMailManager.getNeedSendList();
        if (ZXTCollectionsUtil.isEmpty(userTimeMailList)) {
            return;
        }

        List<Long> userIds = userTimeMailList.stream().map(UserTimeMail::getUserId).distinct().collect(Collectors.toList());
        List<User> userList = userManager.listByIds(userIds);
        Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, Function.identity()));

        for (UserTimeMail userTimeMail : userTimeMailList) {
            log.info("时间邮件接收邮箱：{}，发送时间：{}", userTimeMail.getSendMail(), userTimeMail.getSendTime());
            SendEmailApiDTO emailApiDTO = new SendEmailApiDTO();
            emailApiDTO.setToEmail(userTimeMail.getSendMail());
            emailApiDTO.setSubject("您有一封时间邮件已抵达~ 时间来自" + userTimeMail.getCreateTime());
            emailApiDTO.setContent(userTimeMail.getContentTitle() + "\n\n" + AesUtils.decrypt(userTimeMail.getContent(), userTimeMail.getContentSalt()));
            log.info("邮件内容：{}", JSON.toJSONString(emailApiDTO));
            Boolean isSuccess = mailClient.sendEmail(emailApiDTO);
            if (Objects.nonNull(isSuccess) && isSuccess) {
                userTimeMailManager.updateSendArrive(userTimeMail.getId());
                //为创建时间邮件的人发送 成功通知
                User user = userMap.get(userTimeMail.getUserId());
                if (Objects.nonNull(user)) {
                    SendEmailApiDTO sendEmailApiDTO = new SendEmailApiDTO();
                    sendEmailApiDTO.setToEmail(user.getEmail());
                    sendEmailApiDTO.setSubject("您设置的时间邮件已成功抵达~ 时间来自" + userTimeMail.getCreateTime());
                    sendEmailApiDTO.setContent("邮件标题为：" + userTimeMail.getContentTitle());
                    mailClient.sendEmail(sendEmailApiDTO);
                }
            }
        }
    }
}
